16 research outputs found
Scoped Capabilities for Polymorphic Effects
Type systems usually characterize the shape of values but not their free
variables. However, many desirable safety properties could be guaranteed if one
knew the free variables captured by values. We describe CCsubBox, a calculus
where such captured variables are succinctly represented in types, and show it
can be used to safely implement effects and effect polymorphism via scoped
capabilities. We discuss how the decision to track captured variables guides
key aspects of the calculus, and show that CCsubBox admits simple and intuitive
types for common data structures and their typical usage patterns. We
demonstrate how these ideas can be used to guide the implementation of capture
checking in a practical programming language.Comment: 39 page
Qualifying System F-sub
Type qualifiers offer a lightweight mechanism for enriching existing type
systems to enforce additional, desirable, program invariants. They do so by
offering a restricted but effective form of subtyping. While the theory of type
qualifiers is well understood and present in many programming languages today,
polymorphism over type qualifiers is an area that is less examined. We explore
how such a polymorphic system could arise by constructing a calculus System
F<:Q which combines the higher-rank bounded polymorphism of System F<: with the
theory of type qualifiers. We explore how the ideas used to construct System
F<:Q can be reused in situations where type qualifiers naturally arise -- in
reference immutability, function colouring, and capture checking. Finally, we
re-examine other qualifier systems in the literature in light of the
observations presented while developing System F<:Q.Comment: 24 page
Design and implementation of effect handlers for object-oriented programming languages
An important aspect of software development is to structure the control flow of a
program. Features to structure the control flow range from simple branching between
two possible execution paths, to non-local control-flow transfers
by means of jumps or exceptions. Furthermore, modern programming languages
offer advanced control-flow structures like async/await to avoid blocking
when performing input / output actions, generators to model demand driven
computation of streams, or coroutines to express control-flow transfer between
different software components.
Often, those advanced control-flow abstractions are built into the language and are thus
not user definable. Users are thus limited to the control-flow
features provided by the programming language designers and cannot create
their own custom domain-specific control-flow abstractions.
Another aspect of software development is to parametrize a software
component over details that might vary.
Parametrizing a component with configuration, behavior, or other
components, enables reuse of the same component in different contexts.
Components can be configured statically, or dynamically at runtime.
Manually parametrizing components can quickly become tedious, both for the
component author who needs to design the component for parametrization, as well
as the user of the component who needs to provide all parameters. This is
especially the case for components that depend on other parametrized components.
They often need to be parametrized by all transitive parameters of their
dependencies.
Algebraic effects (Plotkin and Power, 2003) and their extension with handlers
(Plotkin and Pretnar, 2009, 2013) offer interesting new ways to
structure programs. Programs use effect operations, which, like normal
functions, can receive arguments and return results. However, the implementation
of effect operations is left open and depends on the context in which the program is
executed.
Effect handlers, much like exception handlers, handle effect
operations and provide their implementation. Like throwing an exception,
calling an effect operation transfers control to the corresponding handler.
Unlike exceptions, the handler can resume the computation and thus transfer
control back to the call site.
Effect handlers support both aspects of software development
concisely: they can express advanced control-flow structures as well as parametrization of
software components.
It has been shown in the literature that effect handlers can
express many of the aforementioned control-flow structures as libraries, such as
async/await, generators, and coroutines. At the same time,
effect operations can conveniently be used to parametrize software components
while handlers provide the configuration. Unifying both aspects also guarantees
well-defined interaction between control flow and parametrization.
While algebraic effects recently gained popularity in the programming language
research community, we identify two problems hindering adoption by a wider
audience of programmers. Firstly, programmers are immediately
confronted with the full generality of effect handlers. While effect handlers
are expressive enough to model advanced control-flow structures, not all
use cases require this expressivity.
Secondly, algebraic effects and handlers have been conceived in the realm of
functional programming languages. In consequence, most implementations of effect handlers
are either standalone languages following the functional programming paradigm or
are library embeddings into existing functional programming languages.
In this thesis, we propose solutions to the two aforementioned problems
with the goal to facilitate adoption of effect handlers by a wider audience.
To address the first problem, we systematically present effect handlers as a
combination of delimited control (that is, they allow control-flow transfers)
and dynamic binding (that is, they allow parametrization). While the connection
between effect handlers and delimited control has previously been established
and it has been shown that effect handlers can express dynamic binding, we
discover that dynamic binding and effect handlers form a spectrum.
We present a language
design that embraces this spectrum. Increasing
expressivity and conceptual complexity step-by-step, we introduce the three
features ambient values, ambient functions, and ambient control. Ambient
values coincide with dynamically bound variables and ambient control
coincides with a slightly restricted form of effect handlers. The novel
intermediate form of ambient functions enables abstraction similar to
effect handlers, but without modifying the control flow: Ambient functions
are dynamically bound, but statically evaluated. Introducing effect
handlers from dynamic binding offers programmers an alternative way to approach
handlers. They can incrementally learn and understand the different
generalizations (ambient values, functions, and control). We hope this
facilitates adoption of effect handlers by a wider audience.
To address the second problem, we present a library design, which embeds effect
handlers in object-oriented programming languages. Our design embraces the
object-oriented programming paradigm and we map abstractions of effect
handlers to key abstractions of object-oriented programming. Combining the
two paradigms not only enables programmers to use effect handlers in object-oriented
programs, but also to use object-oriented programming abstractions to modularize
effect handlers.
Our design employs explicit capability-passing style. That is, instead
of dynamically searching for a handler at runtime, we pass instances of handlers
as additional arguments to methods.
We present an implementation of our library design in the language Scala.
It is based on a variation of a continuation monad for multi-prompt delimited
control (Dybvig et al., 2007) to allow effect handlers to express advanced control-flow structures.
We study the extensibility properties gained by embedding effect handlers
into an object-oriented programming language.
While it opens up new dimensions of extensibility, the implementation still
comes with two limitations. Firstly, being based on a monad
user programs have to be written in monadic style. Secondly, the implementation
is not effect safe and capabilities can escape the scope of their handler.
This potentially results in runtime errors.
We separately address the two limitations.
Firstly, we present an implementation in Java that performs a type-selective
continuation-passing style transformation by rewriting of bytecode. This way,
user programs in the Java implementation can be written in direct-style
overcoming the limitation of the Scala implementation.
Secondly, we enhance our Scala library with an embedded effect system. We index
the type of effectful programs with an intersection type to track the set of
used effects. Expressing the set of used effects as an intersection type allows
us to reuse Scala's support for subtyping to express effect subtyping and to
reuse Scala's support for type polymorphism to express effect polymorphism
Effects as capabilities: effect handlers and lightweight effect polymorphism
Effect handlers have recently gained popularity amongst programming language researchers. Existing type-and effect systems for effect handlers are often complicated and potentially hinder a wide-spread adoption. We present the language Effekt with the goal to close the gap between research languages with effect handlers and languages for working programmers. The design of Effekt revolves around a different view of effects and effect types. Traditionally, effect types express which side effects a computation might have. In Effekt, effect types express which capabilities a computation requires from its context. While this new point in the design space of effect systems impedes reasoning about purity, we demonstrate that it simplifies the treatment of effect polymorphism and the related issues of effect parametricity and effect encapsulation. To guarantee effect safety, we separate functions from values and treat all functions as second-class. We define the semantics of Effekt as a translation to System E, a calculus in explicit capability-passing style
Type-Level Programming with Match Types
Type-level programming is becoming more and more popular in the realm of functional programming. However, the combination of type-level programming and subtyping remains largely unexplored in practical programming languages. This paper presents \emph{match types}, a type-level equivalent of pattern matching. Match types integrate seamlessly into programming languages with subtyping and, despite their simplicity, offer significant additional expressiveness. We formalize the feature of match types in a calculus based on System F sub and prove its soundness. We practically evaluate our system by implementing match types in the Scala 3 reference compiler, thus making type-level programming readily available to a broad audience of programmers